package com.dtease.agent.core.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.bind.support.WebExchangeBindException;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

/**
 * @description web层异常校验切面
 * @author chentl
 * @class WebFluxExceptionHandler
 * @package com.dtease.agent.exception
 * @since 2025/5/15 09:56
 */
@RestControllerAdvice
public class WebFluxExceptionHandler {

    /**
     * 处理全局异常
     * @author chentl
     * @since 10:42 2025/5/15
     * @param ex ex
     * @return {@link Mono< ResponseEntity< ErrorResponse>>}
     **/
    @ExceptionHandler(Exception.class)
    public Mono<ResponseEntity<ErrorResponse>> handleGlobalException(Exception ex) {
        ex.printStackTrace();

        ErrorResponse errorResponse = new ErrorResponse(
                HttpStatus.INTERNAL_SERVER_ERROR.value(),
                "系统异常",
                null,
                System.currentTimeMillis()
        );

        return Mono.just(ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .contentType(MediaType.APPLICATION_JSON)
                .body(errorResponse));
    }

    /**
     * 处理业务异常
     * @author chentl
     * @since 10:42 2025/5/15
     * @param ex ex
     * @return {@link Mono< ResponseEntity< ErrorResponse>>}
     **/
    @ExceptionHandler(BizException.class)
    public Mono<ResponseEntity<ErrorResponse>> handleBizException(BizException ex) {
        ex.printStackTrace();

        ErrorResponse errorResponse = new ErrorResponse(
                ex.getCode(),
                ex.getMessage(),
                null,
                System.currentTimeMillis()
        );

        return Mono.just(ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .contentType(MediaType.APPLICATION_JSON)
                .body(errorResponse));
    }

    /**
     * 处理参数校验异常
     * @author chentl
     * @since 10:42 2025/5/15
     * @param ex ex
     * @return {@link Mono< ResponseEntity< ErrorResponse>>}
     **/
    @ExceptionHandler(WebExchangeBindException.class)
    public Mono<ResponseEntity<ErrorResponse>> handleValidationException(WebExchangeBindException ex) {
        ex.printStackTrace();

        Map<String, String> errors = new HashMap<>();
        ex.getFieldErrors().forEach(error -> {
            errors.put(error.getField(), error.getDefaultMessage());
        });

        ErrorResponse errorResponse = new ErrorResponse(
                HttpStatus.BAD_REQUEST.value(),
                "参数校验失败",
                errors,
                System.currentTimeMillis()
        );

        return Mono.just(ResponseEntity
                .badRequest()
                .contentType(MediaType.APPLICATION_JSON)
                .body(errorResponse));
    }
}